﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace SharpAnalyzer.Utilities
{
    internal sealed class TypeNameResolver
    {
        public static string GetName(TypeDeclarationSyntax syntax)
        {
            Verify.NotNull(() => syntax);

            string str1 = syntax.Identifier.ValueText;
            string containingTypeName = GetContainingTypeName(((SyntaxNode)syntax).Parent);
            if (!string.IsNullOrWhiteSpace(containingTypeName))
                str1 = containingTypeName + "." + str1;
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(str1);
            if (syntax.TypeParameterList != null)
            {
                SeparatedSyntaxList<TypeParameterSyntax> parameters = syntax.TypeParameterList.Parameters;
                if (parameters.Any())
                {
                    string str2 = string.Join(", ", parameters.Select(x => x.Identifier.ValueText));
                    stringBuilder.AppendFormat("<{0}>", (object)str2);
                }
            }
            return stringBuilder.ToString();
        }

        public static string GetQualifiedName(ITypeSymbol symbol)
        {
            Verify.NotNull(() => symbol);

            string result = symbol.Name;
            string containingTypeName = GetContainingTypeName(symbol.ContainingSymbol);
            if (!string.IsNullOrWhiteSpace(containingTypeName))
                result = containingTypeName + "." + result;
            INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)symbol;
            if (namedTypeSymbol.TypeParameters != null && namedTypeSymbol.TypeParameters.Any())
            {
                result += string.Format("<{0}>",
                    string.Join(", ", namedTypeSymbol.TypeParameters.Select(x => x.Name)));
            }
            for (ISymbol containingSymbol = symbol.ContainingSymbol;
                ((containingSymbol != null) && (containingSymbol.Kind == SymbolKind.Namespace));
                containingSymbol = containingSymbol.ContainingSymbol)
            {
                INamespaceSymbol namespaceSymbol = (INamespaceSymbol)containingSymbol;
                if (namespaceSymbol.IsGlobalNamespace)
                {
                    result += string.Format(", {0}", namespaceSymbol.ContainingAssembly.Name);
                    break;
                }
                result = containingSymbol.Name + "." + result;
            }
            return result;
        }

        private static string GetContainingTypeName(ISymbol symbol)
        {
            INamedTypeSymbol namedTypeSymbol;
            if ((namedTypeSymbol = symbol as INamedTypeSymbol) == null)
                return (string)null;
            string name = namedTypeSymbol.Name;
            string containingTypeName = GetContainingTypeName(namedTypeSymbol.ContainingSymbol);
            if (!string.IsNullOrWhiteSpace(containingTypeName))
                return containingTypeName + "." + name;
            return name;
        }

        private static string GetContainingTypeName(SyntaxNode syntax)
        {
            TypeDeclarationSyntax declarationSyntax;
            if ((declarationSyntax = syntax as TypeDeclarationSyntax) == null)
                return (string)null;

            string valueText = declarationSyntax.Identifier.ValueText;
            string containingTypeName = GetContainingTypeName(((SyntaxNode)declarationSyntax).Parent);
            if (!string.IsNullOrWhiteSpace(containingTypeName))
                return containingTypeName + "." + valueText;
            return valueText;
        }
    }
}
